//-----------------------------------------------------------------------
// <copyright file="Add.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation.  All rights reserved.
// THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY 
// KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A
// PARTICULAR PURPOSE.
// </copyright>
// <author>Andy Reeves</author>
// <email>andyr</email>
// <date>2004-03-23</date>
// <summary>Add performance counters to the local machine</summary>
//-----------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.PerformanceCounters
{
    using System;
    using System.Xml;
    using System.Globalization;
    using System.Diagnostics;

    using Microsoft.Build.Framework;

    /// <summary>
    /// Add performance counters to the local machine
    /// </summary>
    /// <remarks>
    /// <code><![CDATA[<PerformanceCounters.Add CategoryName="categoryName" CategoryHelp="categoryHelp" CounterList="counterList" MultiInstance="c"/>]]></code>
    /// <para>where:</para>
    /// <para><i>categoryName (Required)</i></para>
    /// <para>
    /// The name of the custom performance counter category to create and register with the system. If a performance counter category with 
    /// the specified name already exists, it will be deleted.
    /// </para>
    /// <para><i>categoryHelp (Required)</i></para>
    /// <para>
    /// A description of the custom category.
    /// </para>
    /// <para><i>counterList</i></para>
    /// <para>
    /// An array of task items that specifies the counters to create as part of the new category.
    /// </para>
    /// <para><i>multiInstance</i></para>
    /// <para>
    /// Either true or false. If true then the performance counter will be a multiinstance counter. The default is false (single instance). 
    /// </para>
    /// </remarks>
    /// <example>
    /// <code><![CDATA[
    /// <Project>
    ///     <CustomCounterList Include="foobar.A" CounterName="Counter1" CounterHelp="First custom counter" CounterType="NumberOfItems32"/>
    ///     <CustomCounterList Include="foobar.A" CounterName="Counter2" CounterHelp="Second custom counter" CounterType="NumberOfItems32"/>
    ///     <CustomCounterList Include="foobar.A" CounterName="Counter3" CounterHelp="Third custom counter" CounterType="NumberOfItems32"/>
    ///     <CustomCounterList Include="foobar.A" CounterName="Counter4" CounterHelp="Fourth custom counter" CounterType="NumberOfItems32"/>
    ///     <CustomCounterList Include="foobar.A" CounterName="Counter5" CounterHelp="Last custom counter" CounterType="NumberOfItems32"/>
    ///
    ///     <Target Name="Test">
    ///         <PerformanceCounters.Add
    ///             CategoryName="myCustomCategory"
    ///             CategoryHelp="This is a custom performance counter category"
    ///             CounterList="@(CustomCounterList)"
    ///             MultiInstance="true" />
    ///     </Target>
    /// </Project>
    /// ]]></code>    
    /// </example>
    public class Add : TaskBase
    {
        private string categoryName = String.Empty;
        private string categoryHelp = String.Empty;
        private ITaskItem[] counterList = null;
        private bool multiInstance = false;

        /// <summary>
        /// Initializes a new instance of the AddPerformanceCounters class.
        /// </summary>
        public Add()
        {
        }

        /// <summary>
        /// Performs the action of this task.
        /// </summary>
        protected override void InternalExecute()
        {
            #region Execute code

            CounterCreationDataCollection colCounterCreationData = new CounterCreationDataCollection();
            CounterCreationData objCreateCounter;

            colCounterCreationData.Clear();

            Log.LogMessageFromResources("PerfCounter.AddCategory", categoryName);

            // Always delete as we cannot add counters after category creation
            //
            if (PerformanceCounterCategory.Exists(categoryName))
            {
                Log.LogMessageFromResources(MessageImportance.Low, "PerfCounter.RemoveCategory", categoryName);
                PerformanceCounterCategory.Delete(categoryName);
            }

            // Ensure we get them in order by using looping rather than foreach
            // we need them in order as there are rules for avg counters based on 
            // "base counters"
            for (int taskCount = 0; taskCount < counterList.Length; taskCount++)
            {
                ITaskItem counter = counterList[taskCount];
                string counterName = counter.GetMetadata("CounterName");
                string counterHelp = counter.GetMetadata("CounterHelp");

                PerformanceCounterType counterType = (PerformanceCounterType) (Enum.Parse(typeof(PerformanceCounterType), counter.GetMetadata("CounterType")));
                objCreateCounter = new CounterCreationData(counterName, counterHelp, counterType);
                colCounterCreationData.Add(objCreateCounter);
            }

            if (colCounterCreationData.Count > 0)
            {
                PerformanceCounterCategoryType categoryType = PerformanceCounterCategoryType.SingleInstance;

                if (this.multiInstance)
                {
                    categoryType = PerformanceCounterCategoryType.MultiInstance;
                }

                PerformanceCounterCategory.Create(categoryName, categoryHelp, categoryType, colCounterCreationData);
            }
            #endregion
        }

        /// <summary>
        /// The name of the custom performance counter category to create and register with the system.
        /// </summary>
        /// <value>The name of the custom performance counter category to create and register with the system. If a performance counter category with 
        /// the specified name already exists, it will be deleted.</value>
        [Required]
        public string CategoryName
        {
            get
            {
                return (categoryName == null ? String.Empty : categoryName);
            }
            set
            {
                categoryName = value;

                return;
            }
        }

        /// <summary>
        /// A description of the custom category.
        /// </summary>
        /// <value>A description of the custom category.</value>
        [Required]
        public string CategoryHelp
        {
            get
            {
                return (categoryHelp == null ? String.Empty : categoryHelp);
            }
            set
            {
                categoryHelp = value;

                return;
            }
        }

        /// <summary>
        /// Flag indicating whether to create a multiple instance performance counter. The default (false) creates single instance counters.
        /// </summary>
        public bool MultiInstance
        {
            get { return this.multiInstance; }
            set { this.multiInstance = value; }
        }

        /// <summary>
        /// An array of TaskItems that specifies the counters to create as part of the new category.
        /// </summary>
        /// <value>An array of TaskItems that specifies the counters to create as part of the new category.</value>
        [Required]
        public ITaskItem[] CounterList
        {
            get
            {
                return counterList;
            }
            set
            {
                counterList = value;

                return;
            }
        }
    }
}